package com.yogurt.leetcode.bitoperation;

/**
 * 转换成小写字母
 * 给你一个字符串 s ，将该字符串中的大写字母转换成相同的小写字母，返回新的字符串
 */
public class Solution {
    /**
     * 大写字母 A - Z 的 ASCII 码范围为 [65,90]：
     * 小写字母 a - z 的 ASCII 码范围为 [97,122]。
     * 因此，如果我们发现 ch 的 ASCII 码在 [65,90] 的范围内，那么我们将它的 ASCII 码增加 32，即可得到对应的小写字母。
     *
     * 近而我们可以发现，由于 [65,90] 对应的二进制表示为 [(01000001),(01011010)]，
     * 32 对应的二进制表示为 (00100000)
     * 而对于 [(01000001),(01011010)] 内的所有数，
     * 表示 32 的那个二进制位都是 0，因此可以对 ch 的 ASCII 码与 32 做按位或运算，替代与 32 的加法运算
     * 链接：https://leetcode.cn/problems/to-lower-case/solutions/1151839/zhuan-huan-cheng-xiao-xie-zi-mu-by-leetc-5e29/
     *
     * A：65 a：97  两者之间相差了32
     * Z：90 z：122 两者之间相差了32
     * 数字32的二进制表示为：0010 0000，而[65,90]之间的所有数，表示32的那个二进制位都是0，所以要想在原来的基础上
     * 加32，只需要那个0的位置变成1即可，所以与32的二进制（0010 0000）做或运算，来表示在原来的基础上加了32
     * 如：65的二进制是 0100 0001 ，转换十进制是：1*2^0 + 0*2^1 + 0*2^2 +...+0*2^5+1*2^6 + 0*2^7 = 1 + 64 = 65
     * 32是2的5次方（2^5） 0010 0000
     * 65  0100 0001
     * 32  0010 0000   做 或 运算
     *     0110 0001   可以看到从前往后数第3位，从原来的0，变成了1
     * 所以，再转换为十进制是：1*2^0 + 0*2^1 + 0*2^2 +...+1*2^5 + 1*2^6 + 0*2^7 = 1 + 32 + 64 = 97
     * 97就是对应的小写字母a
     */
    public static void main(String[] args) {
        Solution s = new Solution();
        String result = s.toLowerCase("Hello");
        System.out.println(result);
    }

    public String toLowerCase(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= 65 && c <= 90) {
                c |= 32;
            }
            sb.append(c);
        }
        return sb.toString();
    }
}
